#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
项目名称: 飞鸽内网穿透自动签到
Author: Fidcz
功能：飞鸽内网穿透自动签到
Date: 2021/10/29 14:40
Update: 2022/02/25 12:30
cron: 22 11,18 * * *
new Env('飞鸽内网穿透自动签到');
"""

"""
    已知问题:
        1.遇到网络或其他异常签到失败不推送提示(当前cron一天跑两次，尽量避免出错)
        2.使用print在青龙中不会实时输出日志，需要使用logging
"""

import sys, os
import requests,urllib3
import re
import time
import random
urllib3.disable_warnings()

class fgSign:
    def __init__(self, userName, userPw, sleeptime='0'):
        self.user_agent = self.get_userAgent()
        self.userName = str(userName).strip()
        self.userPw = str(userPw).strip()
        self.sleepTime = sleeptime
        self.hmid = 'e7a29f62e903f02ca46b3f22641eb1cd'
        self.cookie = {}


    def fgMain(self):
        # 延迟启动
        try:
            if int(self.sleepTime) > 0:
                timeLater = random.randint(0, int(self.sleepTime))
                print(f'延迟{str(timeLater)}分钟后执行')
                time.sleep(60 * timeLater)
        except Exception as err:
            print(repr(err))
            print('延迟变量设置错误,无延时启动。正确例子 export fgnwct_sign_time="10"  (环境变量代表延时最大时间min)')
            pass

        self.fgSession = requests.session()

        runResult = None
        print(f'\n\n* 开始签到账号: {self.userName}')
        
        runResult = self.get_html_home()
        if runResult:
            return runResult

        runResult = self.get_html_login()
        if runResult:
            return runResult

        runResult = self.post_login()
        if runResult:
            return runResult

        self.get_sign_cookie()

        runResult = self.get_html_notice()
        if runResult:
            return runResult

        return self.get_signin()

    def get_userAgent(self):
        # 随机获取UA
        user_agent_list = [
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
            'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3324.88 Safari/537.36',
            'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'
        ]

        return user_agent_list[random.randint(0,2)]

    def get_hmid(self, htmlContent):
        """
            获取百度hm ID
        """
        if re.findall(r'hm\.js\?([0-9a-zA-z]{32})', htmlContent):
            self.hmid = re.findall(r'hm\.js\?([0-9a-zA-z]{32})', htmlContent)[0]
        else:
            # 使用默认
            self.hmid = 'e7a29f62e903f02ca46b3f22641eb1cd'

    def get_sign_cookie(self):
        """
            设置追踪cookie
        """
        ga = random.randint(1484902134, 1967435140)
        gid = random.randint(1484902134, 1967435140)

        nowTime = int(time.time())

        self.cookie = {
            'Hm_lvt_{}'.format(self.hmid): str(nowTime),
            'Hm_lpvt_{}'.format(self.hmid): str(nowTime),
            '_ga': 'GA1.2.{}.{}'.format(ga, nowTime),
            '_gid': 'GA1.2.{}.{}'.format(gid, nowTime)
        }

    def get_html_home(self):
        """
        * 访问home
        """
        try:
            url_home = 'https://www.fgnwct.com/home.html'
            header_home = {
                'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.9',
                'sec-fetch-dest': 'document',
                'sec-fetch-mode': 'navigate',
                'sec-fetch-site': 'none',
                'sec-fetch-user': '?1',
                'upgrade-insecure-requests': '1',
                'user-agent': self.user_agent
            }

            respon_home = self.fgSession.get(url=url_home, headers=header_home, verify=False)
            # print('\nhome.html-cookie:', self.fgSession.cookies)

            # print(respon_home.content)

            self.get_hmid(respon_home.text)
            print('\nHMid:', self.hmid)
            time.sleep(1)
            return None
        except Exception as err:
            print('\n访问home出错:', repr(err))
            return '账号:{}  签到失败\n\n访问HOME出错:{}'.format(self.userName, repr(err))

    def get_html_login(self):
        """
        * 访问login
        """
        try:
            # 2.访问login.html
            url_login = 'http://www.fgnwct.com/login.html'
            header_home = {
                'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.9',
                'sec-fetch-dest': 'document',
                'sec-fetch-mode': 'navigate',
                'sec-fetch-site': 'none',
                'sec-fetch-user': '?1',
                'upgrade-insecure-requests': '1',
                'user-agent': self.user_agent
            }

            self.fgSession.get(url=url_login, headers=header_home, verify=False)
            time.sleep(1)
            return None
        except Exception as err:
            print('\n登录login出错:', repr(err))
            return '账号:{}  签到失败\n\n登录login出错:{}'.format(self.userName, repr(err))

    def post_login(self):
        """
        * POST登录请求
        """
        # 3.POST登录请求
        try:
            url_post_login = 'https://www.fgnwct.com/login'
            header_post_login = {
                'accept': '*/*',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.9',
                'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'origin': 'https://www.fgnwct.com',
                'referer': 'https://www.fgnwct.com/login.html',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-origin',
                'user-agent': self.user_agent,
                'x-requested-with': 'XMLHttpRequest'
            }

            data_post_login = {
                'email': self.userName,
                'password': self.userPw,
                'rememberMe': '1'
            }

            respon_post_login = self.fgSession.post(url=url_post_login, data=data_post_login, headers=header_post_login, verify=False)
            if not respon_post_login.json().get('success', False):
                # 出错了
                print('\n登录login状态错误:', respon_post_login.text)
                return '账号:{}  签到失败\n\n登录login状态错误:\n{}'.format(self.userName, respon_post_login.text)
            print('\nPOST登录返回:', respon_post_login.text)
            # print('\n登录后Cookie:', self.fgSession.cookies)
            time.sleep(1)
            return None
        except Exception as err:
            print('\n登录POST login出错:', repr(err))
            return '账号:{}  签到失败\n\n登录POST login出错:{}'.format(self.userName, repr(err))

    def get_html_notice(self):
        """
        * 访问notice
        """
        try:
            # 2.访问dashboard.html
            # url_notice = 'http://www.fgnwct.com/notice.html'
            url_notice = 'https://fgnwct.com/dashboard.html'
            header_home = {
                'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.9',
                'Host': 'fgnwct.com',
                'Referer': 'https://fgnwct.com/home.html',
                'sec-fetch-dest': 'iframe',
                'sec-fetch-mode': 'navigate',
                'sec-fetch-site': 'same-origin',
                'upgrade-insecure-requests': '1',
                'user-agent': self.user_agent
            }

            respon_notice = self.fgSession.get(url=url_notice, headers=header_home, cookies=self.cookie, verify=False)
            if '签到领取积分' not in respon_notice.text:
                print('\n', '今日已签到,跳过')
                return '账号:{}  签到失败\n\n今日已签到'.format(self.userName)
            time.sleep(1)
            return None
        except Exception as err:
            print('\n访问notice出错:', repr(err))
            return None

    def get_signin(self):
        """
        * 发送签到请求
        """
        try:
            url_sign = 'https://www.fgnwct.com/signIn'

            header_sign = {
                'accept': '*/*',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.9',
                'referer': 'https://www.fgnwct.com/notice.html',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-origin',
                'user-agent': self.user_agent,
                'x-requested-with': 'XMLHttpRequest'
            }

            respon_sign = self.fgSession.get(url=url_sign, headers=header_sign, cookies=self.cookie, verify=False)

            print('\n签到返回:', respon_sign.text)

            if 'credits' in respon_sign.json() and 'signDays' in respon_sign.json():
                # 签到成功
                print('\n账号:', self.userName, '签到成功')
                print('\n当前签到天数:{}\n当前积分:{}\n签到获得积分:{}'.format(
                    respon_sign.json().get('signDays', '-1'),
                    respon_sign.json().get('credits', '-1'),
                    respon_sign.json().get('increase', '-1')
                ))
                return '账号:{}  签到成功\n\n当前签到天数:{}\n当前积分:{}\n签到获得积分:{}'.format(
                    self.userName,
                    respon_sign.json().get('signDays', '-1'),
                    respon_sign.json().get('credits', '-1'),
                    respon_sign.json().get('increase', '-1')
                )
            else:
                # 出错
                print('\n签到sign出错:', respon_sign.text)
                return '账号:{}  签到失败\n\n签到sign返回出错:{}'.format(self.userName, respon_sign.text)
                
        except Exception as err:
            print('\n签到sign出错:', repr(err))
            return '账号:{}  签到失败\n\n签到sign出错:{}'.format(self.userName, repr(err))

def loadSend():
    #print("加载推送功能")
    global send
    send = None
    cur_path = os.path.abspath(os.path.dirname(__file__))
    sys.path.append(cur_path)
    if os.path.exists(cur_path + "/sendNotify.py"):
        try:
            from sendNotify import send
        except Exception as e:
            send = None
            print("加载通知服务失败~",e)


if __name__ == '__main__':
    loadSend()

    accountList = []

    try:
        if "fgnwct_sign" in os.environ:
            account = os.environ["fgnwct_sign"]
            if ':' in account:
                accountTemp = account.split('&')
                if len(accountTemp) > 0:
                    for accountT in accountTemp:
                        if len(accountT.split(":")) == 2:
                            if len(accountT.split(":")[0]) > 0 and len(accountT.split(":")[1]) > 0:
                                accountList.append((accountT.split(":")[0], accountT.split(":")[1]))
        if len(accountList) < 1:
            # 单账号 export fgnwct_sign="账号:密码"
            # 多账号 export fgnwct_sign="账号1:密码1&账号2:密码2&..."
            raise Exception('未提供账号密码变量fgnwct_sign或者为空,格式为 账号1:密码1&账号2:密码2')
    except Exception as err:
        print("\n", err)
        if send:
            send('飞鸽签到错误', str(err))
        exit(3)

    if 'fgnwct_sign_time' in os.environ:
        print(os.environ['fgnwct_sign_time'])
        sleepTime = os.environ['fgnwct_sign_time']
    else:
        sleepTime = '0'

    print('共提供了{}个账号'.format(len(accountList)))

    accountLogs = []
    sendLog = ''

    for account in accountList:
        tempLog = fgSign(account[0], account[1], sleepTime).fgMain()
        accountLogs.append(tempLog)
    
    print('\n签到结果:')

    for logIndex in range(len(accountLogs)):
        print('\n\n{}'.format(accountLogs[logIndex]))
        if '今日已签到' in accountLogs[logIndex]:
            # 已签到，不提醒
            accountLogs[logIndex] = ''
        if sendLog == '':
            sendLog += accountLogs[logIndex]
        else:
            sendLog += f'\n\n{accountLogs[logIndex]}'
    
    if sendLog != '':
        if send:
            print(send('飞鸽签到结果', sendLog))
    else:
        print('\n不推送消息')